package com.dailygreetings.dailygreetings.service;

import com.dailygreetings.dailygreetings.bo.*;
import com.dailygreetings.dailygreetings.config.BaseConfig;
import com.dailygreetings.dailygreetings.config.CaiyunConfig;
import com.dailygreetings.dailygreetings.config.WechatConfig;
import com.dailygreetings.dailygreetings.utils.DateUtils;
import com.dailygreetings.dailygreetings.utils.HttpUtils;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.http.HttpHeaders;

import java.util.Collections;


/**
 * @BelongsProject: daily-greetings
 * @BelongsPackage: com.dailygreetings.dailygreetings.service
 * @Author: shanzhengfei
 * @CreateTime: 2024-11-21  17:17
 * @Description: 发送消息service
 * @Version: 1.0
 */

@Log4j2
@Service
@AllArgsConstructor
public class DailyGreetingService {

    private final HttpUtils httpUtils;

    private final WechatConfig wechatConfig;

    private final BaseConfig baseConfig;

    private final CaiyunConfig caiyunConfig;
    private static final String GET_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
    private static final String SEND_MSG = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s";
    private static final String CAI_YUN = "https://api.caiyunapp.com/v2.5/%s/%s/daily.json";
    private static final String YI_YAN = "https://international.v1.hitokoto.cn/?c=d";
    private static final String HUANG_LI = "http://v.juhe.cn/laohuangli/d?date=%s&key=%s";
    private static final String ONE_WORD = "https://api.xygeng.cn/openapi/one";

    /**
     * 获取企微应用发送消息token
     */
    public String getAccessToken() {
        String url = String.format(GET_TOKEN, wechatConfig.getCorpid(), wechatConfig.getCorpsecret());
        ResponseEntity<AccessTokenResponse> response = httpUtils.get(url, AccessTokenResponse.class);

        if (response.getBody() != null && response.getBody().getErrcode() == 0) {
            log.info("获取 Access Token 成功");
            return response.getBody().getAccess_token();
        } else {
            log.error("获取 Access Token 失败: {}", response.getBody() != null ? response.getBody().getErrmsg() : "未知错误");
            return "";
        }
    }

    public void sendDailyGreeting() {
        // 获取发送消息的token
        String accessToken = getAccessToken();
        String url = String.format(SEND_MSG, accessToken);

        SendMessageRequest request = new SendMessageRequest();
        request.setTouser(wechatConfig.getTouser());
        request.setMsgtype("news");
        request.setAgentid(wechatConfig.getAgentid());
        request.setEnable_id_trans(0);
        request.setEnable_duplicate_check(0);
        request.setDuplicate_check_interval(1800);

        SendMessageRequest.News news = new SendMessageRequest.News();
        SendMessageRequest.Article article = new SendMessageRequest.Article();
        article.setTitle(wechatConfig.getNews().getTitle());

        // 获取天气信息
        CaiyunWeatherResponse weatherResponse = getWeather();
        CaiyunWeatherResponse.Daily daily = weatherResponse.getResult().getDaily();
        // 这里获取的是未来几天的 取当天
        CaiyunWeatherResponse.Temperature temperature = daily.getTemperature().get(0);
        CaiyunWeatherResponse.Skycon skycon = daily.getSkycon().get(0);

        // 映射天气描述
        String weatherDesc = mapSkyconToDescription(skycon.getValue());

        // 获取穿衣建议
        String clothingAdvice = getClothingAdvice(temperature.getMax());

        // 获取每日一言
        YiyanResponse hitokotoResponse = getYiYan();
        YiyanResponse.Data hitokoto = hitokotoResponse.getData();

        // 获取黄历信息
        HuangliResponse huangliResponse = getHuangLi();
        HuangliResponse.Result huangLi = huangliResponse.getResult();

        // 动态生成 description 内容并替换占位符
        String description = wechatConfig.getNews().getDescription();
        description = description.replace("{today}", DateUtils.getToday());
        description = description.replace("{weather}", String.format("%s %d ~ %d ℃", weatherDesc, Math.round(temperature.getMin()),
                Math.round(temperature.getMax())));
        description = description.replace("{clothingAdvice}", clothingAdvice);
        description = description.replace("{yinLi}", huangLi.getYinli());
        description = description.replace("{babyDays}", DateUtils.getBabyAge(baseConfig.getBabyDays()));
        description = description.replace("{babyBirthday}", String.valueOf(DateUtils.getDaysUntilBirthday(baseConfig.getBabyDays())));
        description = description.replace("{birthday}", String.valueOf(DateUtils.getDaysUntilBirthday(baseConfig.getBirthday())));
        description = description.replace("{babyDays}", DateUtils.getBabyAge(baseConfig.getBabyDays()));
        description = description.replace("{anniversary}", String.valueOf(DateUtils.getDaysUntilAnniversary(baseConfig.getAnniversary())));
        description = description.replace("{words}", hitokoto.getContent());
        article.setDescription(description);

        article.setUrl(wechatConfig.getNews().getUrl());
        article.setPicurl(wechatConfig.getNews().getPicUrl());
        news.setArticles(Collections.singletonList(article));
        request.setNews(news);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity<String> response = httpUtils.post(url, request, headers, String.class);
//        ResponseEntity<String> response = null;

        if (response.getBody() != null) {
            log.info("发送消息成功 返回信息: " + response.getBody());
        } else {
            log.error("发送失败");
        }
    }

    /**
     * 获取彩云天气信息
     * @return CaiyunWeatherResponse
     */
    public CaiyunWeatherResponse getWeather() {
        String url = String.format(CAI_YUN, caiyunConfig.getToken(), caiyunConfig.getLocation());

        ResponseEntity<CaiyunWeatherResponse> response = httpUtils.get(url, CaiyunWeatherResponse.class);

        if (response.getBody() != null && "ok".equals(response.getBody().getStatus())) {
            log.info("----- 获取彩云天气信息成功 ----- ");
            return response.getBody();
        } else {
            log.error("----- 获取彩云天气信息失败 ----- ");
            throw new RuntimeException("获取彩云天气信息失败");
        }
    }

    /**
     * 映射彩云天气状况描述
     * @param skycon
     * @return
     */
    private String mapSkyconToDescription(String skycon) {
        switch (skycon) {
            case "CLEAR_DAY":
                return "晴";
            case "CLEAR_NIGHT":
                return "晴（夜间）";
            case "PARTLY_CLOUDY_DAY":
                return "多云（白天）";
            case "PARTLY_CLOUDY_NIGHT":
                return "多云（夜间）";
            case "CLOUDY":
                return "阴";
            case "LIGHT_HAZE":
                return "轻度雾霾";
            case "MODERATE_HAZE":
                return "中度雾霾";
            case "HEAVY_HAZE":
                return "重度雾霾";
            case "LIGHT_RAIN":
                return "小雨";
            case "MODERATE_RAIN":
                return "中雨";
            case "HEAVY_RAIN":
                return "大雨";
            case "STORM_RAIN":
                return "暴雨";
            case "FOG":
                return "雾";
            case "LIGHT_SNOW":
                return "小雪";
            case "MODERATE_SNOW":
                return "中雪";
            case "HEAVY_SNOW":
                return "大雪";
            case "STORM_SNOW":
                return "暴雪";
            case "DUST":
                return "浮尘";
            case "SAND":
                return "沙尘";
            case "WIND":
                return "大风";
            default:
                return "未知天气";
        }
    }

    public HitokotoResponse getHitokoto() {
        ResponseEntity<HitokotoResponse> response = httpUtils.get(YI_YAN, HitokotoResponse.class);

        if (response.getBody() != null) {
            log.info("----- 获取每日一言成功 ----- ");
            return response.getBody();
        } else {
            log.error("----- 获取每日一言失败 ----- ");
            throw new RuntimeException("获取每日一言hitokoto失败");
        }
    }

    /**
     * 每日一言
     * @return YiyanResponse
     */
    public YiyanResponse getYiYan() {
        ResponseEntity<YiyanResponse> response = httpUtils.get(ONE_WORD, YiyanResponse.class);

        if (response.getBody() != null) {
            log.info("----- 获取每日一言成功 ----- ");
            return response.getBody();
        } else {
            log.error("----- 获取每日一言失败 ----- ");
            throw new RuntimeException("获取每日一言失败");
        }
    }

    /**
     * 获取黄历信息
     * @return HuangliResponse
     */
    public HuangliResponse getHuangLi() {
        String url = String.format(HUANG_LI, DateUtils.getDay(), baseConfig.getHuangliKey());
        ResponseEntity<HuangliResponse> response = httpUtils.get(url, HuangliResponse.class);

        if (response.getBody() != null) {
            log.info("----- 获取黄历成功 ----- ");
            return response.getBody();
        } else {
            log.error("----- 获取黄历失败 ----- ");
            throw new RuntimeException("获取黄历失败");
        }
    }

    /**
     * 自定义穿衣建议
     * @return String
     */
    public String getClothingAdvice(double maxTemp) {
        if (maxTemp <= -10) {
            return "长款厚羽绒服、毛衣。";
        } else if (maxTemp < 0) {
            return "厚羽绒服、毛衣。";
        } else if (maxTemp < 10) {
            return "厚毛衣、风衣或夹克。";
        } else if (maxTemp < 15) {
            return "中等厚度毛衣或卫衣、长裤。";
        } else if (maxTemp < 20) {
            return "长袖衬衫、薄外套、长裤。";
        } else if (maxTemp < 25) {
            return "短袖衬衫T恤、薄长裤。";
        } else if (maxTemp < 30) {
            return "短袖衬衫T恤、短裤短裙。";
        } else {
            return "短袖T恤、短裤或短裙。";
        }
    }
}
